package com.fanrui.code.chess.mahjong;

import java.util.Collection;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.lang3.RandomUtils;

import com.fanrui.code.chess.ChessGamerManager;
import com.fanrui.code.entity.TableLog;
import com.fanrui.code.player.Player;
import com.fanrui.proto.cmd.MahjongBaseRoomInfo.Builder;
import com.fanrui.proto.cmd.MahjongGameType;
import com.fanrui.proto.cmd.MahjongStep;
import com.fanrui.proto.cmd.MatchGameLevel;
import com.fanrui.proto.cmd.NotityOtherPlayerEnterMahjongDesk;
import com.fanrui.proto.cmd.NotityPlayerLeaveMahjongDesk;
import com.fanrui.proto.cmd.ResJoinMahjongRoom;
import com.fanrui.proto.cmd.ResPlayerLeaveMahjongDesk;

public class MatchMahjongTable extends AbstractMahjongTable<MahjongMatchTableType>{
	private MahjongGameType gameType;
	private MatchGameLevel gameLevel;
	
	private boolean destorying = false;
	public MatchMahjongTable(int ID, MahjongRules gameRules,MahjongGameType gameType,MatchGameLevel gameLevel) {
		super(ID, gameRules, new MahjongMatchTableType());
		this.gameType = gameType;
		this.gameLevel = gameLevel;
	}

	public MatchGameLevel getGameLevel() {
		return this.gameLevel;
	}
	
	public MahjongGameType getGameType() {
		return this.gameType;
	}

	@Override
	public ResJoinMahjongRoom.Result checkEnterCondition(Player player, boolean isReconnect) {
		ResJoinMahjongRoom.Result result = super.checkEnterCondition(player, isReconnect);
		if(result != ResJoinMahjongRoom.Result.Success) {
			return result;
		}
		MahjongGamer gamer = ChessGamerManager.getInstance().findGamer(player.getId(), MahjongGamer.class);
		if (gamer != null && gamer.getTableID() != getID()) {
			return ResJoinMahjongRoom.Result.Gaming;
		}
		return ResJoinMahjongRoom.Result.Success;
	}

	@Override
	public MahjongGamer findOrCreateGamer(Player player) {
		return ChessGamerManager.getInstance().create(player.getId(), getID(), MahjongGamer.class, player.getIp(), player.getX(), player.getY());
	}
	
	

	@Override
	public ResPlayerLeaveMahjongDesk.Result checkExitCondition(Player player) {
		if(step != MahjongStep.Wait){
			return ResPlayerLeaveMahjongDesk.Result.InGaming;
		}
		return ResPlayerLeaveMahjongDesk.Result.Success;
	}

	@Override
	public void notifyPlayerExit(MahjongGamer gamer,NotityPlayerLeaveMahjongDesk.Result exitCode) {
		super.notifyPlayerExit(gamer,exitCode);
		if(!destorying){
			destorying = true;
			destory();
		}
	}
	
	@Override
	public Collection<Long> needLeavePlayers() {
		HashMap<Long,NotityPlayerLeaveMahjongDesk.Result> set = new HashMap<Long,NotityPlayerLeaveMahjongDesk.Result>();
		for(MahjongGamer gamer : getAllGamer()){
			if(gamer.getCurrentyIncome() < gameRules.roomConfig.getEnterLimit()){
				set.put(gamer.getPlayerID(),NotityPlayerLeaveMahjongDesk.Result.UNGOLD);
			}
			if(gamer.getCurrentyIncome() > gameRules.roomConfig.getLeaveLimit()){
				set.put(gamer.getPlayerID(),NotityPlayerLeaveMahjongDesk.Result.PASSGOLD);
			}
		}
		for (long playerID : set.keySet()) {
			exit(playerID,set.get(playerID));
		}
		return set.keySet();
	}

	@Override
	public void otherBuilder(Builder builder) {
		builder.setGameLevel(gameLevel);
		builder.setMGametype(gameType);
	}
	
	/**
	 * 匹配场不记录战绩
	 */
	protected TableLog createTableLog(long playerId, String playerNickName, String logToken, int income,
			String incomeInfo) {
		return null;
	}
	
	@Override
	public void enter(boolean isReconnect, MahjongGamer gamer) {
		startEnterRobot();
		countdownToStart();
	}
	
	/**
	 * 定时添加机器人
	 */
	public void startEnterRobot() {
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				enterRobot();
			}
		}, 5000);
	}
	
	/**
	 * 房间1分钟不开始解散房间
	 */
	public void countdownToStart() {
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				if(isDiss) {
					timer.cancel();
					return;
				}
				destory();
			}
		}, 60000);
	}
	
	public synchronized void enterRobot() {
		int needRobot = gameRules.maximumCapacity() - gamers.size();
		if(needRobot > 0){
			for(int i=0;i<needRobot;i++){
				final int idealSeatNo = getIdelSeatNO();
				MahjongGamer gamer = ChessGamerManager.getInstance().createRobotGamer(getID(), (int)gameRules.getRoomConfig().getEnterLimit(), (int)gameRules.getRoomConfig().getLeaveLimit());
				gamer.setIsReady(false);
				MahjongGamer oldGamer = gamers.putIfAbsent(idealSeatNo, gamer);
				if (oldGamer != null) {
					throw new IllegalArgumentException("座位号错误");
				}
				useSeat(idealSeatNo);
				if(bankID == null || RandomUtils.nextBoolean()){
					bankID = gamer.getPlayerID();
				}
				NotityOtherPlayerEnterMahjongDesk.Builder builder = NotityOtherPlayerEnterMahjongDesk.newBuilder();
				builder.setGamer(gamer.toCmd());


				// 通知其他人有人进入
				NotityOtherPlayerEnterMahjongDesk.Builder notify = NotityOtherPlayerEnterMahjongDesk.newBuilder();
				notify.setGamer(gamer.toCmd());
				broadcast(notify.build());
			}
		}
	}

	@Override
	public synchronized void startGame() {
		// 全部是机器人解散房间
		int robotNumber = 0;
		for (MahjongGamer mg : this.getGamers().values()) {
			if(mg instanceof MahjongRobot) {
				robotNumber++;
			}
		}
		if(robotNumber == this.getGameRules().getRoomConfig().getPlayerNumber()) {
			this.destory();
			return;
		}
		super.startGame();
	}
}

